Skip to content

feat: add FBC catalog Dockerfile for CI without operator-sdk#2204

Open
kaovilai wants to merge 8 commits into
openshift:oadp-devfrom
kaovilai:fbc-catalog-dockerfile
Open

feat: add FBC catalog Dockerfile for CI without operator-sdk#2204
kaovilai wants to merge 8 commits into
openshift:oadp-devfrom
kaovilai:fbc-catalog-dockerfile

Conversation

@kaovilai
Copy link
Copy Markdown
Member

@kaovilai kaovilai commented May 14, 2026

Summary

Add build/Dockerfile.catalog that renders a bundle image into an FBC (File-Based Catalog) catalog image servable via gRPC CatalogSource. This enables CI to install the operator without operator-sdk, using only opm (actively maintained by OLM team).

  • Multi-stage build: opmubi-minimal (builder) → opm (final)
  • Takes BUNDLE_IMG as required build arg, runs opm render to generate FBC
  • Sets /etc/containers/policy.json for pulling from CI registries without signature verification
  • Pre-builds gRPC serving cache at build time (--cache-dir + --cache-only)
  • Mirrors existing make catalog-build Makefile logic

Closes #2203

Reference implementations


Follow-up PRs needed

1. openshift/release CI config update (replaces #79152)

PR #79152 migrated to operator-sdk run bundle workflow. With this Dockerfile, we revert to the standard optional-operators-ci-aws workflow instead. Per-variant diff from current:

# Add to operator stanza:
operator:
  bundles:
  - as: oadp-operator-bundle              # ADD: name the bundle
    dockerfile_path: build/Dockerfile.bundle
    skip_building_index: true             # ADD: don't build deprecated ci-index

# Add catalog image build:
images:
- dockerfile_path: build/Dockerfile.catalog
  build_args:
  - name: BUNDLE_IMG
    value: pipeline:oadp-operator-bundle  # needs verification — see note below
  to: oadp-operator-catalog

# Change in each test's steps:
    dependencies:
      OO_INDEX: oadp-operator-catalog     # was: ci-index
    env:
      OO_CHANNEL: dev                     # KEEP
      OO_PACKAGE: oadp-operator           # KEEP
      OO_TARGET_NAMESPACES: '!install'    # KEEP
      FEATURE_SET: TechPreviewNoUpgrade   # ADD (4.22+ only, from #79152)
    workflow: optional-operators-ci-aws   # KEEP original (NOT operator-sdk variant)

# Remove:
# - base_images.cli-operator-sdk          # no longer needed

Open question: whether ci-operator's build_args resolves pipeline: image references. If not, alternatives: custom CI step that resolves the bundle ref and runs podman build --build-arg, or the Quay operator pattern (custom step-registry entry that creates CatalogSource directly). Details in PR #79152 comment.

2. OLMv1 tests PR #2160

Once the CI config switch lands, #2160 can be rebased. No code changes needed in #2160 itself — it just needs the CI infrastructure (this Dockerfile + the release config update) to be in place first.

Test plan

  • Build bundle: make bundle-build BUNDLE_IMG=ttl.sh/oadp-bundle-test:1h
  • Push bundle: make bundle-push BUNDLE_IMG=ttl.sh/oadp-bundle-test:1h
  • Build catalog: podman build -f build/Dockerfile.catalog --build-arg BUNDLE_IMG=ttl.sh/oadp-bundle-test:1h -t localhost/oadp-catalog:test .
  • Verify catalog serves: podman run --rm -p 50051:50051 localhost/oadp-catalog:test
  • Verify CI config integration (follow-up PR in openshift/release)

Note

Responses generated with Claude

Summary by CodeRabbit

  • New Features

    • Added ability to build and serve an Operator Lifecycle Manager catalog image with automated generation, validation, cache-only serving mode, and gRPC access on port 50051.
  • Chores

    • Updated default OPM tool version to v1.68.0 and added a build target for producing the catalog image.

Add build/Dockerfile.catalog that renders a bundle image into an FBC
(File-Based Catalog) catalog image servable via gRPC CatalogSource.
This enables CI to install the operator without operator-sdk, using
only opm (actively maintained by OLM team).

The Dockerfile uses opm render to generate FBC content from a bundle
image passed as BUNDLE_IMG build arg, appends OLM package/channel
metadata, validates with opm validate, and serves via opm serve.

Pattern follows networking-incubator/coraza-kubernetes-operator and
migrationqe/oadp-release-info ROSA_HCP tooling.

Closes: openshift#2203

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds build/Dockerfile.catalog to render a bundle into an OLM file-based catalog, inject package/channel metadata, validate the catalog, and produce a runtime image that serves the catalog over gRPC. Also bumps Makefile OPM_VERSION to v1.68.0 and adds a catalog-fbc-build target.

Changes

OLM File-Based Catalog (FBC) image + OPM version bump

Layer / File(s) Summary
Dockerfile header & build-stage tooling
build/Dockerfile.catalog
Adds Dockerfile comments; introduces OPM_VERSION build-arg, an opm base stage and a UBI9 builder stage; copies opm into the builder and writes /etc/containers/policy.json to allow insecure bundle pulls.
Index generation, package/channel injection, validation
build/Dockerfile.catalog
Requires BUNDLE_IMG; runs opm render to produce /configs/oadp-operator/index.yaml; appends olm.package and olm.channel entries using VERSION and DEFAULT_CHANNEL; runs opm validate /configs/.
Runtime serve image
build/Dockerfile.catalog
Creates final image from the opm runtime image, copies /configs, runs opm serve --cache-only --cache-dir=/tmp/cache, sets operators.operatorframework.io.index.configs.v1 label to /configs, exposes gRPC port 50051, and sets ENTRYPOINT/CMD.
Makefile: OPM version bump & build target
Makefile
Updates default OPM_VERSION from v1.23.0 to v1.68.0 and adds .PHONY: catalog-fbc-build / catalog-fbc-build to build the catalog image using build/Dockerfile.catalog with BUNDLE_IMG, OPM_VERSION, VERSION, and DEFAULT_CHANNEL build args.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 12
✅ Passed checks (12 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding an FBC (File-Based Catalog) Dockerfile for CI operations that eliminates the operator-sdk dependency.
Description check ✅ Passed The description provides a comprehensive summary with motivation, detailed technical explanation, implementation references, follow-up work, and a test plan covering the required template sections.
Linked Issues check ✅ Passed The PR fully addresses issue #2203's objectives: provides a static FBC catalog Dockerfile, adds a Makefile target for building it, and documents the CI config changes needed to eliminate operator-sdk dependency from the CI workflow.
Out of Scope Changes check ✅ Passed All changes are within scope: new Dockerfile.catalog file, OPM_VERSION bump to match the Dockerfile requirements, and new catalog-fbc-build target directly support the FBC catalog objective from #2203.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Stable And Deterministic Test Names ✅ Passed PR only adds build/Dockerfile.catalog and updates Makefile. No Ginkgo tests present. Check not applicable.
Test Structure And Quality ✅ Passed Custom check for Ginkgo test structure not applicable—PR contains only Dockerfile and Makefile changes with no test code additions or modifications.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests added. Changes are only to build/Dockerfile.catalog and Makefile. MicroShift compatibility check only applies when test code is added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This PR does not add any Ginkgo e2e tests. Changes are limited to build/Dockerfile.catalog and Makefile updates. The SNO test compatibility check is not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed This PR adds build artifacts only (Dockerfile and Makefile target). The check applies when deployment manifests, operator code, or controllers are added/modified. This PR contains none.
Ote Binary Stdout Contract ✅ Passed OTE Binary Stdout Contract check is not applicable. PR adds only build infrastructure (Dockerfile and Makefile), not OTE binaries or test code. No process-level Go code is modified.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests added. PR only modifies build/Dockerfile.catalog and Makefile, which are build/infrastructure files, not test code.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot requested review from mpryc and sseago May 14, 2026 21:04
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 14, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kaovilai

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 14, 2026
Reviewed all 45 releases between v1.23.0 and v1.68.0. No breaking
changes affect the opm render, opm validate, or opm generate
dockerfile commands used in the Makefile catalog-build target.

Notable changes absorbed:
- v1.53.0: requires policy.json for registry access (Dockerfile
  already sets insecureAcceptAnything for CI registries)
- v1.58.0: stricter opm validate (no impact on single-bundle catalog)
- v1.51.0: file permissions ratcheted to o600 (Makefile deletes
  generated files after build anyway)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
build/Dockerfile.catalog (2)

44-54: ⚡ Quick win

Consider adding a non-root USER directive.

The container runs as root by default. Adding a non-root user improves security posture, especially if this image is used outside CI contexts.

OPM catalog images typically support running as non-root. The cache directory /tmp/cache should remain writable for non-root users.

🔒 Proposed fix to run as non-root
 FROM opm
 
 COPY --from=builder /configs /configs
 
 RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
 
 LABEL operators.operatorframework.io.index.configs.v1=/configs
 
 EXPOSE 50051
+
+USER 1001
+
 ENTRYPOINT ["/bin/opm"]
 CMD ["serve", "/configs", "--cache-dir=/tmp/cache"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build/Dockerfile.catalog` around lines 44 - 54, Add a non-root USER and
ensure runtime dirs are writable: create or switch to a dedicated unprivileged
user (e.g., "opmuser") in the Dockerfile, chown /tmp/cache and any config
directories copied from builder (referenced by COPY --from=builder /configs
/configs and the /tmp/cache used by RUN and CMD/ENTRYPOINT) to that user's
UID:GID, and add a USER instruction before ENTRYPOINT so the container runs
non-root while preserving write access to /tmp/cache and /configs.

14-16: 💤 Low value

Consider updating OPM to a more recent version.

OPM v1.23.0 is significantly outdated; the latest available version is v1.66.0. Updating would include numerous bug fixes, security improvements, and feature enhancements released over the intervening versions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build/Dockerfile.catalog` around lines 14 - 16, Update the OPM base image
version by changing the ARG OPM_VERSION value from v1.23.0 to a more recent
stable release (e.g., v1.66.0) so the FROM
quay.io/operator-framework/opm:${OPM_VERSION} AS opm stage pulls the newer OPM;
ensure any downstream compatibility tests are run after bumping ARG OPM_VERSION
to confirm no breaking changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@build/Dockerfile.catalog`:
- Around line 44-54: Add a non-root USER and ensure runtime dirs are writable:
create or switch to a dedicated unprivileged user (e.g., "opmuser") in the
Dockerfile, chown /tmp/cache and any config directories copied from builder
(referenced by COPY --from=builder /configs /configs and the /tmp/cache used by
RUN and CMD/ENTRYPOINT) to that user's UID:GID, and add a USER instruction
before ENTRYPOINT so the container runs non-root while preserving write access
to /tmp/cache and /configs.
- Around line 14-16: Update the OPM base image version by changing the ARG
OPM_VERSION value from v1.23.0 to a more recent stable release (e.g., v1.66.0)
so the FROM quay.io/operator-framework/opm:${OPM_VERSION} AS opm stage pulls the
newer OPM; ensure any downstream compatibility tests are run after bumping ARG
OPM_VERSION to confirm no breaking changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4b612c57-f06f-4173-a272-4fab17b35b17

📥 Commits

Reviewing files that changed from the base of the PR and between 57cc09e and 275962c.

📒 Files selected for processing (1)
  • build/Dockerfile.catalog

Comment thread build/Dockerfile.catalog Outdated
echo 'package: oadp-operator' >> /configs/oadp-operator/index.yaml && \
echo 'entries:' >> /configs/oadp-operator/index.yaml && \
echo " - name: oadp-operator.v${VERSION}" >> /configs/oadp-operator/index.yaml && \
/bin/opm validate /configs/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 30 - 42 seems pretty ugly to me.
alternatives?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one could create a yaml file outside then sed inside here.. etc.. either way.. up to you.. more moving parts.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ours vs coraza-kubernetes-operator catalog/Dockerfile

Aspect Coraza Ours
FBC metadata Pre-committed in repo (coraza-kubernetes-operator/ dir with package/channel YAML). Dockerfile just copies it. Generated inline via heredoc. No files to maintain in repo.
Bundle rendering for img in ${BUNDLE_IMGS} loop — supports multiple bundles Single BUNDLE_IMG — we only have one bundle
Fail-fast None — silently fails if BUNDLE_IMGS empty test -n "${BUNDLE_IMG}" guard with error message
Non-root USER Not set Explicit USER 65532
OPM version v1.64.0 v1.68.0
Bundles dir COPY bundles/ /tmp/bundles/ — copies local bundle content (unused by opm render though) No local bundle content — purely image-based
Cache warmup Yes (--cache-dir=/tmp/cache --cache-only) Same
policy.json Yes (insecureAcceptAnything) Same
Multi-stage opm → ubi-minimal → opm (3 stages) Same pattern

Main difference: coraza pre-commits their FBC package/channel metadata as files, we generate it at build time. Theirs is cleaner if metadata changes rarely. Ours is zero-maintenance — no files to keep in sync with Makefile variables.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced echo chains with a heredoc in the latest push. Much cleaner now. Also added fail-fast guard for missing BUNDLE_IMG and dropped the USER 65532 / chown lines (opm base image is distroless — no /bin/sh, and already runs as non-root USER 1001 since v1.23.2).

Tested locally — catalog builds, serves gRPC, and returns correct package/channel/bundle data. See test results comment above.

Note

Responses generated with Claude

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@build/Dockerfile.catalog`:
- Around line 26-31: The Dockerfile should fail fast and avoid word-splitting
when BUNDLE_IMG is empty: add a guard after ARG BUNDLE_IMG that checks the
variable is set and exits with a clear error if not, and quote the variable in
the opm render invocation (i.e., change the /bin/opm render ${BUNDLE_IMG} call
to use a quoted expansion) so the command uses a single argument and errors are
clearer while still writing to /configs/oadp-operator/index.yaml.
- Around line 44-54: Add an explicit non-root runtime user and make /tmp/cache
writable for it: in the final Dockerfile stage (the stage that contains COPY
--from=builder /configs, ENTRYPOINT ["/bin/opm"], and CMD ["serve", "/configs",
"--cache-dir=/tmp/cache"]) create or ensure /tmp/cache exists and is owned by a
pinned non-root UID (e.g., 65532) and then set USER 65532; specifically, add
commands to mkdir -p /tmp/cache and chown -R 65532:65532 /tmp/cache (and
/configs if needed) before setting USER 65532 so the opm serve process can run
as the non-root user.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 670b4c7e-91bf-4742-8264-aebdfd41a157

📥 Commits

Reviewing files that changed from the base of the PR and between 275962c and ba95d8e.

📒 Files selected for processing (2)
  • Makefile
  • build/Dockerfile.catalog
✅ Files skipped from review due to trivial changes (1)
  • Makefile

Comment thread build/Dockerfile.catalog Outdated
Comment thread build/Dockerfile.catalog
- Replace echo chains with heredoc for OLM metadata (cleaner)
- Add fail-fast guard for missing BUNDLE_IMG build arg
- Quote BUNDLE_IMG in opm render to prevent word-splitting
- Add explicit non-root USER 65532 in final stage
- Ensure /tmp/cache is writable for non-root user

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
@kaovilai kaovilai force-pushed the fbc-catalog-dockerfile branch from 14532d9 to be69539 Compare May 14, 2026 21:18
@kaovilai
Copy link
Copy Markdown
Member Author

Note

Responses generated with Claude

Local sanity check — catalog image builds and serves ✅

Build steps

$ make bundle-build BUNDLE_IMG=ttl.sh/oadp-bundle-14532d98:1h   # ✅
$ podman push ttl.sh/oadp-bundle-14532d98:1h                     # ✅
$ podman build -f build/Dockerfile.catalog \
    --build-arg BUNDLE_IMG=ttl.sh/oadp-bundle-14532d98:1h \
    -t localhost/oadp-catalog:test .                              # ✅

Build log shows opm render, opm validate, and cache warmup all succeed:

[2/3] STEP 7/8: RUN test -n "${BUNDLE_IMG}" ... /bin/opm render "${BUNDLE_IMG}" ...
--> d2310dde812e
[2/3] STEP 8/8: RUN /bin/opm validate /configs/
--> 47d154cec7e2
...
time="..." level=info msg="building cache" cache=/tmp/cache configs=/configs
Successfully tagged localhost/oadp-catalog:test

Runtime verification

$ podman run --rm -d -p 50051:50051 localhost/oadp-catalog:test
$ podman logs oadp-catalog-test
time="..." level=info msg="serving registry" cache=/tmp/cache configs=/configs port=50051

gRPC queries

$ grpcurl -plaintext localhost:50051 api.Registry/ListPackages
{ "name": "oadp-operator" }

$ grpcurl -plaintext -d '{"name":"oadp-operator"}' localhost:50051 api.Registry/GetPackage
{ "name": "oadp-operator", "channels": [{ "name": "dev", "csvName": "oadp-operator.v99.0.0" }], "defaultChannelName": "dev" }

$ grpcurl -plaintext -d '{"pkgName":"oadp-operator","channelName":"dev"}' localhost:50051 api.Registry/GetBundleForChannel
{ "csvName": "oadp-operator.v99.0.0", "packageName": "oadp-operator", "channelName": "dev", "csvJson": "...(full CSV)...", "bundlePath": "ttl.sh/oadp-bundle-14532d98:1h", ... }

All three gRPC APIs return valid data. The catalog correctly serves the oadp-operator package on the dev channel with the full CSV and CRD bundle.

Review feedback addressed

  • Echo chains → heredoc (cleaner)
  • Added BUNDLE_IMG fail-fast guard
  • Quoted ${BUNDLE_IMG} in opm render
  • Removed USER 65532 / mkdir / chown — opm base image has no /bin/sh (distroless-like), already runs as non-root (USER 1001 since v1.23.2)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
build/Dockerfile.catalog (1)

48-58: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit non-root USER in the final stage.

Trivy flags this image as running as root (DS-0002). The opm base image does not guarantee a non-root USER across versions. To harden the image, pin a non-root UID and ensure /tmp/cache is writable for that user before switching.

Note: A previous review suggested this fix and marked it as addressed, but the directive appears to be missing from the current code.

🔒 Suggested hardening patch
 FROM opm
 
 COPY --from=builder /configs /configs
+RUN mkdir -p /tmp/cache && chown -R 65532:0 /configs /tmp/cache
+USER 65532
 
 RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"]
 
 LABEL operators.operatorframework.io.index.configs.v1=/configs
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build/Dockerfile.catalog` around lines 48 - 58, Final Dockerfile stage
currently runs as root; add an explicit non-root user and ensure /tmp/cache is
writable before switching. In the final stage (the block that uses FROM opm,
COPY --from=builder, RUN ["/bin/opm", "serve", ...], ENTRYPOINT ["/bin/opm"],
CMD ["serve", ...]) create a dedicated user/group with a fixed UID/GID, mkdir
/tmp/cache and chown it to that user, and then add a USER instruction to switch
to that non-root account so the container runs non-root while preserving the
current ENTRYPOINT/CMD.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@build/Dockerfile.catalog`:
- Around line 48-58: Final Dockerfile stage currently runs as root; add an
explicit non-root user and ensure /tmp/cache is writable before switching. In
the final stage (the block that uses FROM opm, COPY --from=builder, RUN
["/bin/opm", "serve", ...], ENTRYPOINT ["/bin/opm"], CMD ["serve", ...]) create
a dedicated user/group with a fixed UID/GID, mkdir /tmp/cache and chown it to
that user, and then add a USER instruction to switch to that non-root account so
the container runs non-root while preserving the current ENTRYPOINT/CMD.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 109a4894-79b2-4323-a384-7ac866e1a500

📥 Commits

Reviewing files that changed from the base of the PR and between 14532d9 and be69539.

📒 Files selected for processing (1)
  • build/Dockerfile.catalog

@weshayutin
Copy link
Copy Markdown
Contributor

weshayutin commented May 14, 2026

@rayfordj do you by chance have an example dockerfile for the FBC containers?

@kaovilai
Copy link
Copy Markdown
Member Author

CI config PR updated: openshift/release#79327 replaces openshift/release#79152. Uses Dockerfile.catalog from this PR with build_args + optional-operators-ci-aws workflow (no operator-sdk).

Note

Responses generated with Claude

@kaovilai
Copy link
Copy Markdown
Member Author

This needs to be cherry-picked to oadp-1.3, oadp-1.4, oadp-1.5, oadp-1.6, and oadp-dev branches. Index image building is deprecated and will be removed from ci-operator, so all branches need Dockerfile.catalog for the CI migration in openshift/release#79327.

Note

Responses generated with Claude

Comment thread Makefile
KUSTOMIZE_VERSION ?= v5.2.1
CONTROLLER_TOOLS_VERSION ?= v0.16.5
OPM_VERSION ?= v1.23.0
OPM_VERSION ?= v1.68.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OPM_VERSION is now defined in both Makefile and build/Dockerfile.catalog. These might drift in the future. Two options to tackle this for now:

  • add a Makefile target for this Dockerfile that passes --build-arg OPM_VERSION=$(OPM_VERSION)
  • at minimum, add a comment in each file pointing to the other. Either way, one source of truth is better than two.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catalog file is used by ci in prow and not triggered via makefile, at least no reason too just yet.. but will update any/create targets to have such + comments crosspointing

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added:

  • Cross-pointing comments in both Makefile (line 10) and build/Dockerfile.catalog (line 14)
  • New make catalog-fbc-build target that passes --build-arg OPM_VERSION=$(OPM_VERSION) so the Makefile is the single source of truth when building locally
  • Usage example in both files

Note

Responses generated with Claude

kaovilai and others added 4 commits May 18, 2026 16:36
Add comments cross-pointing between Makefile and Dockerfile.catalog
to prevent OPM_VERSION drift. Add catalog-fbc-build target that passes
OPM_VERSION as --build-arg for single-source-of-truth builds.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
Show how to use the built catalog image with both OLMv0
(CatalogSource + deploy-olm) and OLMv1 (ClusterExtension).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
OLMv0 uses gRPC serving (ENTRYPOINT/CMD/cache). OLMv1 reads /configs
directly and does not need the serve entrypoint.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 427-429: The Makefile comment/example references CATALOG_IMG but
the deploy-olm target actually reads THIS_CATALOG_IMAGE; update the example
invocation (and the matching example in build/Dockerfile.catalog) to use
THIS_CATALOG_IMAGE instead of CATALOG_IMG so the built tag is passed into the
deploy-olm target; search for the deploy-olm target and any example usages in
build/Dockerfile.catalog and replace the variable name accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 63b574aa-2e2e-4ab5-9708-1c0b11a26ff9

📥 Commits

Reviewing files that changed from the base of the PR and between be69539 and 5997aa0.

📒 Files selected for processing (2)
  • Makefile
  • build/Dockerfile.catalog

Comment thread Makefile
Comment on lines +427 to +429
# Then install on-cluster:
# OLMv0 (CatalogSource + Subscription):
# make deploy-olm CATALOG_IMG=$(CATALOG_IMG)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the variable that deploy-olm actually reads.

deploy-olm ignores CATALOG_IMG; the target-specific variable is THIS_CATALOG_IMAGE, so this example won't install the tag the reader just built. Please update this snippet, and the matching example in build/Dockerfile.catalog, to use the right variable.

Suggested doc fix
 # Then install on-cluster:
 #   OLMv0 (CatalogSource + Subscription):
-#     make deploy-olm CATALOG_IMG=$(CATALOG_IMG)
+#     make deploy-olm THIS_CATALOG_IMAGE=$(CATALOG_IMG)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Then install on-cluster:
# OLMv0 (CatalogSource + Subscription):
# make deploy-olm CATALOG_IMG=$(CATALOG_IMG)
# Then install on-cluster:
# OLMv0 (CatalogSource + Subscription):
# make deploy-olm THIS_CATALOG_IMAGE=$(CATALOG_IMG)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 427 - 429, The Makefile comment/example references
CATALOG_IMG but the deploy-olm target actually reads THIS_CATALOG_IMAGE; update
the example invocation (and the matching example in build/Dockerfile.catalog) to
use THIS_CATALOG_IMAGE instead of CATALOG_IMG so the built tag is passed into
the deploy-olm target; search for the deploy-olm target and any example usages
in build/Dockerfile.catalog and replace the variable name accordingly.

Inline comment after ?= caused trailing space in variable value,
breaking the opm download URL in CI.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 18, 2026

@kaovilai: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/unit-test b41a7df link true /test unit-test

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI: Add FBC catalog Dockerfile for Prow operator installation without operator-sdk

3 participants